<template>
  <el-dialog
    v-bind="$attrs"
    :title="$t('flyparam.compare')"
    width="70%"
    v-on="$listeners"
    @open="open"
    @close="close"
  >
    <div class="flex justify-center mb-5">
      <el-input
        style="width: 200px"
        size="small"
        class="mr-3"
        :value="compareName"
        disabled
      />
      <el-button-group size="small" class="mr-3">
        <el-tooltip
          content="Show all Datas"
          placement="bottom"
          :open-delay="500"
        >
          <el-button
            :type="activeFilter.indexOf('all') > -1 ? 'primary' : ''"
            size="small"
            @click="selectFilter('all')"
            >{{ $t('common.all') }}</el-button
          >
        </el-tooltip>
        <el-tooltip
          content="Filter equal datas"
          placement="bottom"
          :open-delay="500"
        >
          <el-button
            :type="activeFilter.indexOf('equal') > -1 ? 'primary' : ''"
            size="small"
            @click="selectFilter('equal')"
            >=</el-button
          >
        </el-tooltip>
        <el-tooltip
          :open-delay="500"
          content="Filter datas that are unequal"
          placement="bottom"
        >
          <el-button
            :type="activeFilter.indexOf('notEqual') > -1 ? 'primary' : ''"
            size="small"
            @click="selectFilter('notEqual')"
            >≠</el-button
          >
        </el-tooltip>
        <el-tooltip
          :open-delay="500"
          content="Filter valuable data on the left and empty data on the right"
          placement="bottom"
        >
          <el-button
            :type="activeFilter.indexOf('right') > -1 ? 'primary' : ''"
            size="small"
            @click="selectFilter('right')"
            >→</el-button
          >
        </el-tooltip>
        <el-tooltip
          :open-delay="500"
          content="Filter valuable data on the right and empty data on the left"
          placement="bottom"
        >
          <el-button
            :type="activeFilter.indexOf('left') > -1 ? 'primary' : ''"
            size="small"
            @click="selectFilter('left')"
            >←</el-button
          >
        </el-tooltip>
      </el-button-group>
      <el-select
        v-model="selectedEntity"
        v-loadmore="loadMore"
        size="small"
        filterable
        @change="selectionChange"
      >
        <el-option
          v-for="data in _entityTable"
          :key="data.$id"
          :value="data.$id"
          :label="isRefTable ? data.$label : data.name"
        />
      </el-select>
    </div>
    <div class="px-3">
      <el-table
        ref="table"
        v-loading="loading"
        :default-expanded-keys="defaultExpandIds"
        header-cell-class-name="table-cell"
        :load="loadTree"
        :data="filteredTableData"
        row-key="key"
        lazy
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        @expand-change="handleExpandChange"
      >
        <template #empty>
          <div>
            <p v-if="!selectedEntity">{{ $t('flyparam.compare_tip1') }}</p>
            <p v-else>{{ $t('common.no_data') }}</p>
          </div></template
        >
        <el-table-column :label="$t('flyparam.show_name')" prop="label" />
        <el-table-column :label="$t('flyparam.value')" prop="value1">
          <template v-slot="scope">
            <div v-if="scope.row.data1 && scope.row.data1.length > 1">
              <span class="py-1 inline-block w-full">{{
                scope.row.value1
              }}</span>
              <el-select
                v-model="scope.row.selectedValue1"
                size="small"
                @change="(val) => handleValueSelectChange(scope.row, val)"
              >
                <el-option
                  v-for="item in scope.row.data1"
                  :key="item"
                  :value="item"
                  :label="item"
                />
              </el-select>
            </div>
            <span v-else>{{ scope.row.value1 }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="compare" align="center">
          <template v-slot="scope">{{
            symbolFilter(scope.row.compare)
          }}</template>
        </el-table-column>
        <el-table-column :label="$t('flyparam.value')" prop="value2">
          <template v-slot="scope">
            <div v-if="scope.row.data2 && scope.row.data2.length > 1">
              <span class="py-1 inline-block w-full">{{
                scope.row.value2
              }}</span>
              <el-select
                v-model="scope.row.selectedValue2"
                size="small"
                @change="(val) => handleValueSelectChange(scope.row, val)"
              >
                <el-option
                  v-for="item in scope.row.data2"
                  :key="item"
                  :value="item"
                  :label="item"
                />
              </el-select>
            </div>
            <span v-else>{{ scope.row.value2 }}</span>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </el-dialog>
</template>

<script>
import {
  getProfileEntryRealValue,
  getEntryByName,
  getRefTableEntryRealValue,
  getReferenceEntryRecord,
  getProfileEntryList
} from '@/api/parameter'
import { uuidv4, deepClone, isObjectBoolean } from '@/utils'

const compare = (value1, value2) => {
  let v1, v2
  v1 = isObjectBoolean(value1) ? value1.toString() : value1
  v2 = isObjectBoolean(value2) ? value2.toString() : value2
  if (!v1 && !v2) {
    return 'equal'
  }
  if (v1 && !v2) {
    return 'right'
  } else if (!v1 && v2) {
    return 'left'
  }
  if (v1 && v2) {
    if (v1 === v2) {
      return 'equal'
    } else {
      return 'notEqual'
    }
  }
  return 'equal'
}

export default {
  props: {
    name1: {
      type: String
    },
    name2: {
      type: String
    },
    tableId: {
      type: String
    },
    entityId: {
      type: String
    },
    entryId: {
      type: String
    },
    templateId: {
      type: String,
      default: ''
    },
    compareName: {
      type: String
    },
    isRefTable: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      activeFilter: ['all'],
      tableData: [],
      tableCopy: [],
      tableTreeRefreshTool: {},
      selectedEntity: '',
      loading: false,
      resolve: null,
      globalId: 1,
      defaultExpandIds: [],
      entityTable: [],
      page: 1,
      pageSize: 10,
      total: 1
    }
  },
  computed: {
    _entityTable() {
      return this.entityTable.filter((v) => v.id !== this.entityId)
    },
    filteredTableData() {
      if (this.activeFilter.includes('all')) {
        return this.tableData
      } else {
        return this.tableData.filter((data) => {
          if (data.children.length > 0) {
            return this.activeFilter.includes(data.children[0].compare)
          }
          return this.activeFilter.includes(data.compare)
        })
      }
    }
  },
  methods: {
    symbolFilter(val) {
      const symbols = {
        equal: '=',
        notEqual: '≠',
        left: '←',
        right: '→'
      }

      return symbols[val]
    },
    fetchData(id) {
      let request = null
      if (this.isRefTable) {
        request = getRefTableEntryRealValue
      } else {
        request = getProfileEntryRealValue
      }

      return new Promise((resolve, reject) => {
        request(this.templateId, this.tableId, id).then((res) => {
          resolve(res)
        })
      })
    },

    async fetchReferenceEntryRecords() {
      try {
        const res = await getReferenceEntryRecord(
          this.templateId,
          this.entryId || this.tableId,
          {
            pageNo: this.page,
            pageSize: this.pageSize
          }
        )
        this.total = res.total
        this.entityTable.push(...res.data)
      } catch (error) {
        this.entityTable = []
        this.$message.error(error)
      }
    },

    async fetchEntryList() {
      if (this.total <= this.entityTable.length) {
        return
      }
      try {
        const res = await getProfileEntryList(
          this.templateId,
          this.entryId || this.tableId,
          {
            pageNo: this.page,
            pageSize: this.pageSize
          }
        )
        this.total = res.rows
        this.entityTable.push(...res.data)
      } catch (error) {
        this.entityTable = []
        this.$message.error(error)
      }
    },

    async fetchReferenceEntryRecord() {
      console.log(this.total, this.entityTable.length)
      if (this.total <= this.entityTable.length) {
        return
      }
      try {
        const res = await getReferenceEntryRecord(
          this.templateId,
          this.tableId,
          {
            pageNo: this.page,
            pageSize: this.pageSize
          }
        )
        this.total = res.total
        const arr = res.items.map((_) => ({
          $label: _.$label[0],
          $id: _.$id[0]
        }))
        this.entityTable.push(...arr)
      } catch (error) {
        this.entityTable = []
        this.$message.error(error)
      }
    },

    fetchTableEntryValue(tableId, entityId) {
      return new Promise((resolve, reject) => {
        getRefTableEntryRealValue(this.templateId, tableId, entityId)
          .then((res) => {
            resolve(res)
          })
          .catch((err) => {
            reject(err.message)
          })
      })
    },

    fetchEntryByName(tableId, entryName) {
      return new Promise((resolve, reject) => {
        getEntryByName(this.templateId, tableId, entryName)
          .then((res) => {
            resolve(res)
          })
          .catch((err) => {
            reject(err)
          })
      })
    },

    fetchReferenceData(tree) {
      return new Promise((resolve) => {
        Promise.all([
          this.fetchEntryByName(tree.refTableSchemaId, tree.selectedValue1),
          this.fetchEntryByName(tree.refTableSchemaId, tree.selectedValue2)
        ]).then((res) => {
          Promise.all([
            this.fetchTableEntryValue(tree.refTableSchemaId, res[0].id),
            this.fetchTableEntryValue(tree.refTableSchemaId, res[1].id)
          ]).then(([arr1, arr2]) => {
            resolve([arr1, arr2])
          })
        })
      })
    },

    async loadTree(tree, treeNode, resolve) {
      // this.resolve = resolve
      tree.children = []
      tree.expanded = true
      tree.resolve = resolve
      console.log(tree)
      try {
        const [arr1, arr2] = await this.fetchReferenceData(tree)
        const child = {
          key: uuidv4(),
          value1: arr1[0].values[0],
          value2: arr2[0].values[0],
          data1: arr1[0].values.length > 1 ? arr1[0].values : '',
          data2: arr2[0].values.length > 1 ? arr2[0].values : '',
          refTableSchemaId: arr1[0].refTableSchemaId,
          selectedValue1: arr1[0].values.length > 1 ? arr1[0].values[0] : '',
          selectedValue2: arr2[0].values.length > 1 ? arr2[0].values[0] : '',
          hasChildren: arr1[0].values.length > 1 || arr2[0].values.length > 1,
          compare: compare(arr1[0].values[0], arr2[0].values[0])
        }

        tree.children.push(child)

        resolve([child])
        this.tableCopy = deepClone(this.tableData)
      } catch (err) {
        console.log(err)
        resolve()
      }
    },

    handleExpandChange(row, expanded) {},

    selectFilter(filter) {
      if (filter === 'all') {
        this.activeFilter = ['all']
        this.tableData = this.tableCopy
      } else {
        if (this.activeFilter.includes(filter)) {
          const index = this.activeFilter.indexOf(filter)
          this.activeFilter.splice(index, 1)
        } else if (this.activeFilter.includes('all')) {
          this.activeFilter = []
          this.activeFilter.push(filter)
        } else {
          this.activeFilter.push(filter)
        }
      }
    },
    // 表格内下拉框发生改变时调用的函数
    async handleValueSelectChange(row, val) {
      if (row.resolve) {
        row.children = []
        const [arr1, arr2] = await this.fetchReferenceData(row)
        const child = {
          key: uuidv4(),
          value1:
            arr1[0].values.length > 1
              ? `${arr1[0].values.join(',')}`
              : arr1[0].values[0],
          value2:
            arr2[0].values.length > 1
              ? `${arr2[0].values.join(',')}`
              : arr2[0].values[0],
          refTableSchemaId: arr1[0].refTableSchemaId,
          data1: arr1[0].values.length > 1 ? arr1[0].values : '',
          data2: arr2[0].values.length > 1 ? arr2[0].values : '',
          hasChildren: arr1[0].values.length > 1 || arr2[0].values.length > 1,
          selectedValue1: arr1[0].values.length > 1 ? arr1[0].values[0] : '',
          selectedValue2: arr2[0].values.length > 1 ? arr2[0].values[0] : '',
          compare: compare(arr1[0].values[0], arr2[0].values[0])
        }
        row.children.push(child)
        if (row.expanded) {
          row.resolve([child])
        }
      }
    },

    selectionChange(val) {
      this.tableData = []
      this.loading = true
      Promise.all([this.fetchData(this.entityId), this.fetchData(val)]).then(
        (res) => {
          this.loading = false
          res[0].forEach((item, index) => {
            res[0][index].value2 = res[1][index].values
          })
          this.tableData = res[0].map((item, index) => {
            let value1 = ''
            let value2 = ''
            value1 =
              item.values.length > 1
                ? `${item.values.join(',')}`
                : item.values[0]
            value2 =
              item.value2.length > 1
                ? `${item.value2.join(',')}`
                : item.value2[0]

            return {
              key: index,
              ...item,
              value1,
              value2,
              selectedValue1: item.values.length > 1 ? item.values[0] : '',
              selectedValue2: item.value2.length > 1 ? item.value2[1] : '',
              compare: compare(item.values[0], item.value2[0]),
              children: [],
              hasChildren: item.type === 5 && item.values.length > 1,
              data1: item.values.length > 1 ? item.values : '',
              data2: item.value2.length > 1 ? item.value2 : ''
            }
          })

          this.tableCopy = deepClone(this.tableData)

          // this.tableData = this.tableData.filter(
          //   (data) => data.compare !== 'equal'
          // )
        }
      )
    },
    open() {
      if (this.isRefTable) {
        this.fetchReferenceEntryRecord()
      } else {
        this.fetchEntryList()
      }
      // this.selectedEntity = this._entityTable[0].id
    },
    close() {
      Object.assign(this.$data, this.$options.data())
    },

    loadMore() {
      if (this.isRefTable) {
        this.page++
        this.fetchReferenceEntryRecord()
      } else {
        this.page++
        this.fetchEntryList()
      }
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .table-cell .cell {
  word-break: break-word;
}
</style>
